#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::istringstream;
using std::vector;
using std::ifstream;
using std::ofstream;
//流程思路分析：
//in 2000 这里面对应的便是_word和_frequency
//把上述的in  2000作为一个整体去看待，那么便是一个record对象
//这里面会有很多很多的record对象，所以最终在dictionary里面
//存储的是vector<Record>里面存储的便是所有的单词的词频对应信息
//the 245
//begining 29
//....
class Record{
public:
    Record(string word, int frequency)
    :_word(word)
    ,_frequency(frequency)
    {

    }
    friend class Dictionary;
private:
    string _word;
    int _frequency;
};
class Dictionary{
public:
    Dictionary(int capacity){
        _dict.reserve(capacity);
    }
    //读取输入文件，截取每个单词
    //针对每出现的一个单词需要进行词频的统计
    //如何统计呢？
    //第一次出现肯定是直接设置1，后续出现+1操作
    //对应的代码：第一次出现需要创建record对象，后续
    //再次出现那么只需要将record对象里面的词频+1操作即可
    //解析单词的过程中有两种处理方式
    //1.先读取一行，然后对一行字符进行解析(istringstream)
    //2.ifs >> word每次读取一个单词
    //判断这个单词里面有没有数字或者其他的非法字符
    //如果有则返回false；如果没有则返回true
    bool is_word(const string & word){
        //获取的是首元素的迭代器，可以理解为是指向
        //首元素的指针
        auto it = word.begin();
        //不断地移动指针，不断判断每一位是否是数字
        //如果是数字，则直接返回false
        //如果全部遍历一遍，都没有返回false，则最终返回true
        while(it != word.end()){
            if(!isalpha(*it)){
                return false;
            }
            ++it;
        }
        return true;
    }
    void read(const string & filename){
        ifstream ifs(filename);
        string line;
        while(getline(ifs, line)){
            istringstream iss(line);
            string word;
            while(iss >> word){
                //判断是否是字母单词
                //word里面只有大小写字母
                if(is_word(word)){
                    //判断word是否是第一次出现？？
                    size_t i = 0;
                    for(;i < _dict.size(); ++i){
                        if(_dict[i]._word == word){
                            //之前已经出现过了
                            ++_dict[i]._frequency;
                            break;
                        }
                    }
                    //如果全部遍历结束之后都没有遇到相等的
                    //说明是第一次出现
                    if(i == _dict.size()){
                        _dict.push_back(Record(word, 1));
                    }
                }
            }
        }
    }
    //将词频信息输出到文件中显示出来即可
    void store(const string & filename){
        ofstream ofs(filename);
#if 0
        for(auto & ele : _dict){
            //ele的真实类型是什么？？？Record
            ofs << ele._word << " " << ele._frequency << endl;
        }
#endif
        //使用迭代器再来实现一遍
        auto it = _dict.begin();
        while(it != _dict.end()){
            //以下两种方式均可以
            //此时迭代器对象是不是就像透明膜一样
            ofs << it->_word << " " << it->_frequency << endl;
            //ofs << (*it)._word << " " << (*it)._frequency << endl;

            ++it;
        }
    
        ofs.close();
    }

private:
    vector<Record> _dict;
};


void test(){
    //面向对象和面向过程的编程语言之间书写的区别
    Dictionary dict(10000);
    dict.read("The_Holy_Bible.txt");
    dict.store("bible.data");
}

int main()
{
    test();
    return 0;
}

